package old.day20190321.dbutils;

import org.apache.commons.dbutils.QueryLoader;
import org.apache.commons.dbutils.QueryRunner;
import org.apache.commons.dbutils.ResultSetHandler;
import org.apache.commons.dbutils.handlers.*;

import java.io.IOException;
import java.sql.Connection;
import java.sql.Date;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * @author DingZhenYun
 * @create 2019-03-21 16:32
 */
/**
 * 1. ResultSetHandler 的作用: QueryRunner 的 query 方法的返回值最终取决于
 * query 方法的 ResultHandler 参数的 hanlde 方法的返回值.
 *
 * 2. BeanListHandler: 把结果集转为一个 Bean 的 List, 并返回. Bean 的类型在
 * 创建 BeanListHanlder 对象时以 Class 对象的方式传入. 可以适应列的别名来映射
 * JavaBean 的属性名:
 * String sql = "SELECT id, name customerName, email, birth " +
 *			"FROM customers WHERE id = ?";
 *
 * BeanListHandler(Class<T> type)
 *
 * 3. BeanHandler: 把结果集转为一个 Bean, 并返回. Bean 的类型在创建 BeanHandler
 * 对象时以 Class 对象的方式传入
 * BeanHandler(Class<T> type)
 *
 * 4. MapHandler: 把结果集转为一个 Map 对象, 并返回. 若结果集中有多条记录, 仅返回
 * 第一条记录对应的 Map 对象. Map 的键: 列名(而非列的别名), 值: 列的值
 *
 * 5. MapListHandler: 把结果集转为一个 Map 对象的集合, 并返回.
 * Map 的键: 列名(而非列的别名), 值: 列的值
 *
 * 6. ScalarHandler: 可以返回指定列的一个值或返回一个统计函数的值.
 */
public class TestDBUtills {

    public static void main(String[] args) throws IOException {
        TestDBUtills testDBUtills=new TestDBUtills();
        //testDBUtills.testQueryRunnerUpdate();
        //testDBUtills.testQuery();
        //testDBUtills.testBeanHanlder();
//        testDBUtills.testBeanListHanlder();
        testDBUtills.testMapHandler();
        testDBUtills.testMapListHandler();
        testDBUtills.testScalarHandler();
        testDBUtills.testQueryLoader();
    }

    class MyResultSetHander implements ResultSetHandler{

        @Override
        public Object handle(ResultSet rs) throws SQLException {
            List<Customer> customers=new ArrayList<>();
            while (rs.next()){
                Integer id=rs.getInt(1);
                String name=rs.getString(2);
                String emial=rs.getString(3);
                Date date=rs.getDate(4);
                Customer customer=new Customer(id,name,emial,date);
                customers.add(customer);
            }
            return customers;
        }
    }
    /**
     * 测试 QueryRunner 类的 update 方法
     * 该方法可用于 INSERT, UPDATE 和 DELETE
     */
    private  void testQueryRunnerUpdate() {

        //1. 创建 QueryRunner 的实现类
        QueryRunner qr=new QueryRunner();
        String sql="update examstudent set Type=? where FileId=?";
        Connection connection=null;
        try{
            connection=JDBCTools.getConnection();
            qr.update(connection,sql,6,1);
        }catch (Exception e){
            e.printStackTrace();
        }finally {
            JDBCTools.releaseDB(null,null,connection);
        }
    }
    //查询操作
    /**
     * 2. 调用 query 方法:
     * ResultSetHandler 参数的作用: query 方法的返回值直接取决于
     * ResultSetHandler 的 hanlde(ResultSet rs) 是如何实现的. 实际上, 在
     * QueryRunner 类的 query 方法中也是调用了 ResultSetHandler 的 handle()
     * 方法作为返回值的。
     */
    public void testQuery(){
        QueryRunner queryRunner=new QueryRunner();
        Connection connection=null;
        try {
            connection=JDBCTools.getConnection();
            String sql="select id,name,email,birth from customer";
            Object o=queryRunner.query(connection,sql,new MyResultSetHander());
            System.out.println(o);
        }catch (Exception e){
            e.printStackTrace();
        }finally {
            JDBCTools.releaseDB(null,null,connection);
        }
    }
    /*
    BeanHander：把结果集的第一条记录转为创建BeanHander对象时传入的Class参数对象
     */
    public void testBeanHanlder(){
          QueryRunner queryRunner=null;
        Connection connection=null;
        try{
            queryRunner=new QueryRunner();
            connection=JDBCTools.getConnection();
            String sql="select id,name,email,birth from customer where id>=?";
            Customer customer= (Customer) queryRunner.query(connection,sql,new BeanHandler(Customer.class),1);
            System.out.println(customer);
        }catch (Exception e){
            e.printStackTrace();
        }finally {
            JDBCTools.releaseDB(null,null,connection);
        }
    }
    /**
     * 测试 ResultSetHandler 的 BeanListHandler 实现类
     * BeanListHandler: 把结果集转为一个 Bean 的 List.
     * List不为NULL,但可以为空集合
     * 该 Bean的类型在创建 BeanListHandler 对象时传入:
     *
     * new BeanListHandler<>(Customer.class)
     *List中存放创建BeanListHanlder传入的class对象对应的对象
     */
    public void testBeanListHanlder(){
        QueryRunner queryRunner=null;
        Connection connection=null;
        try{
            queryRunner=new QueryRunner();
            connection=JDBCTools.getConnection();
            String sql="select id,name,email,birth from customer ";
            List<Customer> customer=  queryRunner.query(connection,sql,new BeanListHandler<>(Customer.class));
            System.out.println(customer);
        }catch (Exception e){
            e.printStackTrace();
        }finally {
            JDBCTools.releaseDB(null,null,connection);
        }
    }
    //返回sql对应的第一天记录对应的Map对象
    //MapHandler: 把结果集转为一个 Map 对象, 并返回. 若结果集中有多条记录, 仅返回
	 //第一条记录对应的 Map 对象. Map 的键: 列名(而非列的别名), 值: 列的值
    public void testMapHandler(){
        QueryRunner queryRunner=null;
        Connection connection=null;
        try{
            queryRunner=new QueryRunner();
            connection=JDBCTools.getConnection();
            String sql="select id,name,email,birth from customer ";
            Map<String,Object> result=queryRunner.query(connection,sql,new MapHandler());
            System.out.println(result);
        }catch (Exception e){
            e.printStackTrace();
        }finally {
            JDBCTools.releaseDB(null,null,connection);
        }
    }
    /*


     * Map 的键: 列名(而非列的别名), 值: 列的值
     *
     */
    public void testMapListHandler(){
        QueryRunner queryRunner=null;
        Connection connection=null;
        try{
            queryRunner=new QueryRunner();
            connection=JDBCTools.getConnection();
            String sql="select id,name,email,birth from customer ";
            List<Map<String,Object>> result=queryRunner.query(connection,sql,new MapListHandler());
            System.out.println(result);
        }catch (Exception e){
            e.printStackTrace();
        }finally {
            JDBCTools.releaseDB(null,null,connection);
        }
    }
   // 6. ScalarHandler: 可以返回指定列的一个值或返回一个统计函数的值.
    public void testScalarHandler(){
        QueryRunner queryRunner=null;
        Connection connection=null;
        try{
            queryRunner=new QueryRunner();
            connection=JDBCTools.getConnection();
            String sql="select count(*) from customer ";
            Object result=queryRunner.query(connection,sql,new ScalarHandler());
            System.out.println(result);
        }catch (Exception e){
            e.printStackTrace();
        }finally {
            JDBCTools.releaseDB(null,null,connection);
        }
    }
    /**
     * QueryLoader: 可以用来加载存放着 SQL 语句的资源文件.
     * 使用该类可以把 SQL 语句外置化到一个资源文件中. 以提供更好的解耦
     * @throws IOException
     */
    public void testQueryLoader() throws IOException {
        Map<String,String> sqls= QueryLoader.instance().load("E:\\IdeaProjects\\JDBC\\src\\sql.properties");
        String s=sqls.get("UPDATE_CUSTOMER");
        System.out.println(s);
    }
}
